package org.jeecg.modules.demo3.fly.utils;


import java.io.*;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
import java.util.Arrays;

public class Base_Conversion {

    /**
     *  short 转换为byte数组    低字节在前
     * @param num
     * @return
     */
    public static byte[] short2byteLittleEndian(short num) {
        byte[] str = new byte[2];
        str[0] = (byte) (num % 256);
        str[1] = (byte) ((num >> 8) % 256);
        return str;
    }

    /**
     *  byte数组转为short  低字节在前
     * @param str
     * @return
     */
    public static short byte2shortLittleEndian(byte[] str) {
        if (str == null || str.length != 2)
            return -1;
        short num = 0;
        num += str[0] & 0x00FF;
        num += (str[1] << 8) & 0xFF00;
        return num;
    }

    /**
     *  float 转  byte
     * @param f
     * @return
     */
    public static byte[] float2byte(float f) {

        // 把float转换为byte[]
        int fbit = Float.floatToIntBits(f);
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            b[i] = (byte) (fbit >> (24 - i * 8));
        }
        // 翻转数组
        int len = b.length;
        // 建立一个与源数组元素类型相同的数组
        byte[] dest = new byte[len];
        // 为了防止修改源数组，将源数组拷贝一份副本
        System.arraycopy(b, 0, dest, 0, len);
        byte temp;
        // 将顺位第i个与倒数第i个交换
        for (int i = 0; i < len / 2; ++i) {
            temp = dest[i];
            dest[i] = dest[len - i - 1];
            dest[len - i - 1] = temp;
        }
        return dest;
    }


    /**
     *  byte 转 float
     * @param b    字节（至少4个字节）
     * @param index   开始位置
     * @return
     */
    public static float byte2float(byte[] b, int index) {
        int l;
        l = b[index + 0];
        l &= 0xff;
        l |= ((long) b[index + 1] << 8);
        l &= 0xffff;
        l |= ((long) b[index + 2] << 16);
        l &= 0xffffff;
        l |= ((long) b[index + 3] << 24);
        return Float.intBitsToFloat(l);
    }


    /**
     *  int 转 byte 低字节在前
     * @param num
     * @return
     */
    public static byte[] int2byteLittleEndian(int num) {
        byte[] str = new byte[4];
        str[0] = (byte) (num % 256);
        str[1] = (byte) ((num >> 8) % 256);
        str[2] = (byte) ((num >> 16) % 256);
        str[3] = (byte) ((num >> 24) % 256);
        return str;
    }


    /**
     *  byte  转  int
     * @param str
     * @return
     */
    public static int byte2int(byte[] str) {
        if (str == null || str.length > 4)
            return -1;
        int num = 0;
        for (int i = str.length - 1; i >= 0; i--) {
            int tmp = (str.length - 1 - i) * 8;
            num += (str[i] << tmp) & (0xFF << tmp);
        }
        return num;
    }

    /**
     *  byte  转  int    LittleEndian
     * @param str
     * @return
     *   序列号
     */
    public static int byte2intLittleEndian(byte[] str) {
        if (str == null || str.length > 4)
            return -1;
        int num = 0;
        for (int i = str.length - 1; i >= 0; i--) {
            int tmp = i * 8;
            num += (str[i] << tmp) & (0xFF << tmp);
        }
        return num;
    }

    /*
    * wjn
    *  留饭
    * */
    public static int byte3intLittleEndian(byte[] str) {
        int value=0;
        for(int i = 0; i < str.length; i++) {
            int shift= i * 8;
            value += (str[i] << shift) & (0xFF << shift);
        }
        return value;
    }



    /**
     *  double 转byte
     * @param d
     * @return
     */
    public static byte[] double2Bytes(double d) {
        long value = Double.doubleToRawLongBits(d);
        byte[] byteRet = new byte[8];
        for (int i = 0; i < 8; i++) {
            byteRet[i] = (byte) ((value >> 8 * i) & 0xff);
        }
        return byteRet;
    }


    /**
     *  byte转 double
     *
     * @param arr
     * @return
     */
    public static double bytes2Double(byte[] arr) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value |= ((long) (arr[i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }



    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    /**
     *  保留小数位数
     * @param value
     * @param str
     * @return
     */
    public static String format(Object value, String str) {
        DecimalFormat df = new DecimalFormat(str);
        df.setRoundingMode(RoundingMode.HALF_UP);
        return df.format(value);

    }


    /**
     *  数组长度值为8，每个值代表bit，即8个bit。bit7 -> bit0
     *  bit数组，bit7 -> bit0
     */
    public static byte[] byteToBitOfArray(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }


    /**
     *  Byte转Bit
     */
    public static String byteToBit(byte b) {
        return "" +
                (byte) ((b >> 7) & 0x1) +
                (byte) ((b >> 6) & 0x1) +
                (byte) ((b >> 5) & 0x1) +
                (byte) ((b >> 4) & 0x1) +
                (byte) ((b >> 3) & 0x1) +
                (byte) ((b >> 2) & 0x1) +
                (byte) ((b >> 1) & 0x1) +
                (byte) ((b >> 0) & 0x1);
    }


    /**
     *   Bit字符串形式转Byte
     */
    public static byte BitToByte(String byteStr) {
        int re, len;
        if (null == byteStr) {
            return 0;
        }
        len = byteStr.length();
        if (len != 4 && len != 8) {
            return 0;
        }
        if (len == 8) {  // 8 bit处理
            if (byteStr.charAt(0) == '0') { // 正数
                re = Integer.parseInt(byteStr, 2);
            } else { // 负数
                re = Integer.parseInt(byteStr, 2) - 256;
            }
        } else { //4 bit处理
            re = Integer.parseInt(byteStr, 2);
        }
        return (byte) re;
    }


    /**
     *  合并数组
     * @param first
     * @param rest
     * @return
     */
    public static byte[] concatAll(byte[] first, byte[]... rest) {
        int totalLength = first.length;
        for (byte[] array : rest) {
            totalLength += array.length;
        }
        byte[] result = Arrays.copyOf(first, totalLength);
        int offset = first.length;
        for (byte[] array : rest) {
            System.arraycopy(array, 0, result, offset, array.length);
            offset += array.length;
        }
        return result;
    }

    /**
     *  byte数组转 float数组(方法貌似不对)
     * @param data
     * @return
     */
    public static float[] byteArrayToFloatArray(byte[] data) {
        ByteArrayInputStream bas = new ByteArrayInputStream(data);
        DataInputStream ds = new DataInputStream(bas);
        float[] fArr = new float[data.length / 4];
        try {
            for (int i = 0; i < fArr.length; i++) {
                fArr[i] = ds.readFloat();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fArr;
    }

    /**
     *  float数组转byte数组(方法貌似不对)
     * @param data
     * @return
     */
    public static byte[] floatArrayToByteArray(float[] data) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(out);
        for (int i = 0; i < data.length; i++) {
            try {
                dataOutputStream.writeFloat(data[i]);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //翻转数组
        byte[] arr1 = new byte[out.toByteArray().length];
        for (int x = 0; x < out.toByteArray().length; x++) {
            arr1[x] = out.toByteArray()[out.toByteArray().length - x - 1];
        }
        return arr1; //如需要翻转数组则返回
        //  return out.toByteArray();  //如不需要翻转数组则返回
    }

    /**
     *   将boolean转成byte[]
     * @param val
     * @return byte[]
     */
    public static byte[] Boolean2ByteArray(boolean val) {
        int tmp = (val == false) ? 0 : 1;
        return ByteBuffer.allocate(4).putInt(tmp).array();
    }

    /**
     *  将byte[]转成boolean
     * @param data
     * @return boolean
     */
    public static boolean ByteArray2Boolean(byte[] data) {
        if (data == null || data.length < 4) {
            return false;
        }
        int tmp = ByteBuffer.wrap(data, 0, 4).getInt();
        return (tmp == 0) ? false : true;
    }


    /**
     *  复制数组到目标数组
     * @param desarray  目标数组
     * @param desindex  复制到目标数组的起始位置
     * @param srcarray  源数组
     * @param scrindex  从源数组复制数据的起始位置
     * @param num       复制的长度
     */
    public static void mymemcpy(byte[] desarray, short desindex, byte[] srcarray, short scrindex, int num) {
        while (num > 0) {
            desarray[desindex] = srcarray[scrindex];
            desindex++;
            scrindex++;
            num--;
        }
    }









    /**
     * 字节数组转16进制
     *
     * @param bytes 需要转换的byte数组
     * @return 转换后的Hex字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() < 2) {
                sb.append(0);
            }
            sb.append(hex);
        }
        return sb.toString();
    }







}
